<?php

namespace Fendx\Middleware;

use Fendx\Di;
use Fendx\Exception\AccessDeniedException;
use Fendx\Exception\BizException;
use Fendx\Exception\ExitException;
use Fendx\Funcs\FendxArray;
use Fendx\Logger;
use Fendx\Router\Middleware\MiddlewareInterface;
use Fendx\Router\Middleware\RequestHandler;

class ApiRendererMiddleware implements MiddlewareInterface
{

    public function process($request, RequestHandler $handler)
    {
        $request = Di::factory()->getRequest();
        $response = Di::factory()->getResponse();

        //请求Controller，如果发生异常，那么返回结果
        try {
            //执行controller
            $res = $handler->handle($request);
            if (FendxArray::isArray($res)) {
                $_res = [
                    'code' => 0,
                    'msg' => 'ok',
                    'data' => null,
                ];

                isset($res['code']) && $_res['code'] = $res['code'];
                isset($res['msg']) && $_res['msg'] = $res['msg'];
                isset($res['data']) && $_res['data'] = $res['data'];

                if (!isset($res['code'])
                    && !isset($res['msg'])
                ) {
                    $_res['data'] = $res;
                }
                $result = $response->json($_res, JSON_UNESCAPED_UNICODE);
            } else {
                $result = $res;
            }
        } catch (ExitException $e) {
            //正常退出直接输出内容
            $result = $e->getData();
        }
        catch (BizException $e) {

            $response->status(400);
            $result = $this->render($request, $response, $e);

        } catch (\Throwable $e) {

            $httpCode = $e->getCode() == 0 ? 500 : $e->getCode();
            $response->status($httpCode);
            $result = $this->render($request, $response, $e, $httpCode);

        }

        return $result;
    }

    private function render($request, $response, \Throwable $e, $code = null) {

        $result = $response->json([
            'code' => $code ?? $e->getCode(),
            'msg' => $e->getMessage(),
            //'data' => null,
        ], JSON_UNESCAPED_UNICODE);

        //记录异常日志
        Logger::exception(basename($e->getFile()), $e->getFile(), $e->getLine(), $e->getMessage(), $e->getCode(), $e->getTraceAsString(), array(
            "action" => $request->header("HOST") . $request->server("REQUEST_URI"),
            "server_ip" => gethostname(),
        ));

        return $result;
    }
}
